package com.cloudsea.yunhaistores.service.impl;

import com.cloudsea.yunhaistores.dto.CartOperationDTO;
import com.cloudsea.yunhaistores.entity.Skus;
import com.cloudsea.yunhaistores.entity.Spus;
import com.cloudsea.yunhaistores.mapper.SkusMapper;
import com.cloudsea.yunhaistores.mapper.SpusMapper;
import com.cloudsea.yunhaistores.service.ShoppingCartService;
import com.cloudsea.yunhaistores.vo.ShoppingCartVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ShoppingCartServiceImpl implements ShoppingCartService {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private SkusMapper skusMapper;
    @Autowired
    private SpusMapper spusMapper; // 需要注入SpusMapper来获取SPU信息

    private static final String CART_KEY_PREFIX = "cart:";

    @Override
    public void add(CartOperationDTO dto) {
        // 1. 校验SKU是否存在且在售
        Skus sku = skusMapper.selectById(dto.getSkuId());
        if (sku == null || sku.getStatus() != 1 || sku.getStock() <= 0) {
            throw new RuntimeException("该商品规格不存在或已售罄");
        }

        // 2. 执行Redis操作
        String cartKey = CART_KEY_PREFIX + dto.getSessionId();
        String skuId = dto.getSkuId().toString();
        redisTemplate.opsForHash().increment(cartKey, skuId, 1);
    }

    @Override
    public void subtract(CartOperationDTO dto) {
        String cartKey = CART_KEY_PREFIX + dto.getSessionId();
        String skuId = dto.getSkuId().toString();

        // 数量减1
        Long newQuantity = redisTemplate.opsForHash().increment(cartKey, skuId, -1);

        // 如果减少后数量小于等于0，则从购物车中移除该商品
        if (newQuantity != null && newQuantity <= 0) {
            redisTemplate.opsForHash().delete(cartKey, skuId);
        }
    }

    @Override
    public ShoppingCartVO getCart(String sessionId) {
        String cartKey = CART_KEY_PREFIX + sessionId;
        // 1. 从Redis获取购物车的所有SKU ID和数量
        Map<Object, Object> cartEntries = redisTemplate.opsForHash().entries(cartKey);

        if (CollectionUtils.isEmpty(cartEntries)) {
            // 如果购物车为空，返回一个规范的空VO对象
            ShoppingCartVO emptyCart = new ShoppingCartVO();
            emptyCart.setItems(new ArrayList<>());
            emptyCart.setTotalQuantity(0);
            emptyCart.setTotalAmount(0L);
            return emptyCart;
        }

        // 2. 提取所有SKU ID，并一次性从数据库查询SKU详情
        List<Long> skuIds = cartEntries.keySet().stream()
                .map(key -> Long.parseLong((String) key))
                .collect(Collectors.toList());
        List<Skus> skuList = skusMapper.selectBatchIds(skuIds);

        // 3. 提取所有SPU ID，并一次性查询SPU详情
        List<Long> spuIds = skuList.stream().map(Skus::getSpuId).distinct().collect(Collectors.toList());
        Map<Long, Spus> spuMap = spusMapper.selectBatchIds(spuIds).stream()
                .collect(Collectors.toMap(Spus::getId, spu -> spu));

        // 4. 组装成VO
        int totalQuantity = 0;
        long totalAmount = 0L;
        List<ShoppingCartVO.CartItemVO> cartItems = new ArrayList<>();

        for (Skus sku : skuList) {
            // 从Redis的Map中获取该SKU的数量
            Object quantityObj = cartEntries.get(sku.getId().toString());
            if (quantityObj == null) continue; // 防御性编程，防止数据不一致
            int quantity = Integer.parseInt((String) quantityObj);

            // 从spuMap中获取对应的SPU信息
            Spus spu = spuMap.get(sku.getSpuId());

            cartItems.add(new ShoppingCartVO.CartItemVO(spu, sku, quantity));
            totalQuantity += quantity;
            totalAmount += sku.getPrice() * quantity;
        }

        ShoppingCartVO shoppingCartVO = new ShoppingCartVO();
        shoppingCartVO.setItems(cartItems);
        shoppingCartVO.setTotalQuantity(totalQuantity);
        shoppingCartVO.setTotalAmount(totalAmount);
        return shoppingCartVO;
    }

    @Override
    public void clearCart(String sessionId) {
        String cartKey = CART_KEY_PREFIX + sessionId;
        redisTemplate.delete(cartKey);
    }
}